Temporaries May Vanish Before You Expect

Contents|Index|Previous|Next
Temporaries may vanish before you expect

It is dangerous to use pointers or references to portions of a temporary object. The compiler may very well delete the object before you expect it to, leaving a pointer to garbage. The most common place where this problem crops up is in classes like the `libg++` string class, that define a conversion function to type char * or const char *. However, any class that returns a pointer to some internal structure is potentially subject to this problem.

For instance, a program may use a function, strfunc , that returns string objects, and another function, charfunc , that operates on pointers to char, as in the following example.

    string strfunc ();
    void charfunc (const char *);

In this situation, it may seem natural to write ‘charfunc (strfunc());’ based on the knowledge that class String has an explicit conversion to char pointers. However, what really happens is akin to
‘charfunc (strfunc().convert());’, where the convert method is a function to do the same data conversion normally performed by a cast. Since the last use of the temporary String object is the call to the conversion function, the compiler may delete that object before actually calling charfunc. The compiler has no way of knowing that deleting the String object will invalidate the pointer. The pointer then points to garbage, so that by the time charfunc is called, it gets an invalid argument.

Code like this may run successfully under some other compilers, especially those that delete temporaries relatively late. However, the GNU C++ behavior is also standard-conforming, so if your program depends on late destruction of temporaries it is not portable.

If you think this is surprising, you should be aware that the ANSI C++ committee continues to debate the lifetime-of-temporaries problem.

For now, at least, the safe way to write such code is to give the temporary a name, which forces it to remain until the end of the scope of the name. For instance, use the following declaration.

    string& tmp = strfunc ();
    charfunc (tmp);